import SysUserModel from "../../dao/model/system/SysUserModel";
import SysRoleModel from "../../dao/model/system/SysRoleModel";
import SysUserEntity, { IUserModel } from "../../entities/system/SysUserEntity";
import { IPageResponse } from "../../types/CommonType";
import { ServerError, ValidationError } from "../../utils/errors";
import { IRoleModel } from "../../entities/system/SysRoleEntity";
import { decrypt } from "../../utils/jsencrypt";
import md5 from "md5";
import { getAvatar, pick } from "../../utils/tools";
import SysParamsSettingModel from "../../dao/model/system/SysParamsSettingModel";
import { ISysParamsSettingModel } from "../../entities/system/SysParamsSettingEntity";
export class SysUserService {
  /**
   * 添加数据
   */
  public static async add(admin: SysUserEntity): Promise<null> {
    // 1. 转换类型
    admin = SysUserEntity.transform(admin);
    // 2. 数据验证
    const errors = await admin.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }

    const roles: IRoleModel[] = [];
    if (admin.roleIds) {
      for (const roleId of admin.roleIds.split(",")) {
        const role = await SysRoleModel.findByPk<IRoleModel>(roleId);
        if (role) {
          roles.push(role);
        } else {
          throw new ValidationError(`角色id ${roleId} 不存在`);
        }
      }
    }

    // 如果没有头像则随机选择一个
    if (!admin.avatar) {
      admin.avatar = await getAvatar();
    }

    const loginPwd = decrypt(admin.loginPwd);
    admin.loginPwd = md5(loginPwd);

    try {
      const user = await SysUserModel.create<IUserModel>(admin as any);
      await user.setRole(roles);
    } catch (error) {
      if (error.name === "SequelizeUniqueConstraintError") {
        throw new ValidationError("该账号已存在");
      }
      throw error;
    }

    return null;
  }

  /**
   * 分页获取数据
   */
  public static async findByPage(current: number, size: number, where?: any): Promise<IPageResponse> {
    let data = await SysUserModel.findAndCountAll<IUserModel>({
      offset: size * (current - 1),
      limit: size,
      where,
    });

    /**
     * 添加角色信息
     */
    for (const item of data.rows) {
      const roleIds = await item.getRole();
      if (roleIds.length) {
        item.dataValues.roleIds = roleIds.map(({ dataValues }) => dataValues.id).join(",");
        item.dataValues.roleNames = roleIds.map(({ dataValues }) => dataValues.roleName).join(",");
      }
    }

    const result: IPageResponse = {
      total: data.count,
      list: data.rows.map((item) => item.dataValues),
    };

    return result;
  }

  public static async findByList(where?: any) {
    return SysUserModel.findAll<IUserModel>({
      where,
    });
  }

  /**
   * 通过id获取数据
   */
  public static async findById(id: string) {
    const data = await SysUserModel.findByPk<IUserModel>(id);
    if (!data) {
      return null;
    }
    const roleIds = await data.getRole();
    if (roleIds.length) {
      data.dataValues.roleIds = roleIds.map(({ dataValues }) => dataValues.id).join(",");
      data.dataValues.roleNames = roleIds.map(({ dataValues }) => dataValues.roleName).join(",");
    }

    return data;
  }

  /**
   * 修改数据
   */
  public static async update(data: SysUserEntity) {
    // 1. 转换类型
    data = SysUserEntity.transform(data);
    // 2. 数据验证
    const errors = await data.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }

    const roles: IRoleModel[] = [];
    if (data.roleIds) {
      for (const roleId of data.roleIds.split(",")) {
        const role = await SysRoleModel.findByPk<IRoleModel>(roleId);
        if (role) {
          roles.push(role);
        } else {
          throw new ValidationError(`角色id ${roleId} 不存在`);
        }
      }
    }

    const user = await SysUserModel.findByPk<IUserModel>(data.id);
    if (user) {
      await user.setRole(roles);
    }

    return SysUserModel.update(data, {
      where: {
        id: data.id,
      },
    });
  }

  public static async updateProfile(data: SysUserEntity) {
    return SysUserModel.update(pick(data, ["nickname", "phone", "sex", "email"]), {
      where: {
        id: data.id,
      },
    });
  }

  public static async updateProfilePwd(data: any) {
    data.oldLoginPwd = md5(decrypt(data.oldLoginPwd));
    data.newLoginPwd = md5(decrypt(data.newLoginPwd));

    if (data.oldLoginPwd === data.newLoginPwd) {
      throw new ValidationError("新旧密码一致");
    }

    const user = await SysUserModel.findByPk<IUserModel>(data.id);
    if (user?.dataValues.loginPwd !== data.oldLoginPwd) {
      throw new ValidationError("旧密码错误");
    }

    await SysUserModel.update<IUserModel>(
      { loginPwd: data.newLoginPwd },
      {
        where: {
          id: data.id,
        },
      }
    );
    return null;
  }

  /**
   * 删除数据
   */
  public static async delete(id: string) {
    return SysUserModel.destroy({
      where: {
        id,
      },
    });
  }

  public static async getInfo(id: string) {
    const user = await SysUserModel.findByPk<IUserModel>(id);
    if (!user) {
      throw new ServerError("数据不存在", 500);
    }
    return { user };
  }

  public static async resetPwd(id: any) {
    // 将默认密码查出来
    const param = await SysParamsSettingModel.findOne<ISysParamsSettingModel>({
      where: {
        paramsCode: "sys_user_init_pwd",
      },
    });
    if (param) {
      const value = md5(param.dataValues.paramsValue);
      await SysUserModel.update(
        { loginPwd: value },
        {
          where: {
            id,
          },
        }
      );
    } else {
      throw new ServerError("重置失败，无法得到默认密码", 500);
    }

    return null;
  }
}
